package com;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint("/notice/{id}")
public class WsController {


//    public static LinkService linkService;
//
//    public static ChatService chatService;
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 在线人数
     */
    public static int onlineNumber = 0;
    /**
     * 以用户的姓名为key，WebSocket为对象保存起来
     */
    private static Map<String, WsController> clients = new ConcurrentHashMap<String, WsController>();
    /**
     * 会话
     */
    private Session session;
    /**
     * 用户id
     */
    private String id;
    /**
     * 建立连接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("id") String id, Session session)
    {
        onlineNumber++;
        logger.info("现在来连接的客户id："+session.getId()+"用户名："+id);
        this.id = id;
        this.session = session;
        logger.info("有新连接加入！ 当前在线人数" + onlineNumber);
        try {
            //messageType 1代表上线 2代表下线 3代表在线名单 4代表普通消息
            //先给所有人发送通知，说我上线了
            Map<String,Object> map1 = Maps.newHashMap();
            map1.put("messageType",1);
            map1.put("id",id);
            sendMessageAll(JSON.toJSONString(map1),id);

            //把自己的信息加入到map当中去
            clients.put(id, this);
            //给自己发一条消息：告诉自己现在都有谁在线
            Map<String,Object> map2 = Maps.newHashMap();
            map2.put("messageType",3);
            //移除掉自己
            Set<String> set = clients.keySet();
            map2.put("onlineUsers",set);
            sendMessageTo(JSON.toJSONString(map2),id);
        }
        catch (IOException e){
            logger.info(id+"上线的时候通知所有人发生了错误");
        }



    }

    @OnError
    public void onError(Session session, Throwable error) {
        logger.info("服务端发生了错误"+error.getMessage());
        //error.printStackTrace();
    }
    /**
     * 连接关闭
     */
    @OnClose
    public void onClose()
    {
        onlineNumber--;
        //webSockets.remove(this);
        clients.remove(id);
        try {
            //messageType 1代表上线 2代表下线 3代表在线名单  4代表普通消息
            Map<String,Object> map1 = Maps.newHashMap();
            map1.put("messageType",2);
            map1.put("onlineUsers",clients.keySet());
            map1.put("id",id);
            sendMessageAll(JSON.toJSONString(map1),id);
        }
        catch (IOException e){
            logger.info(id+"下线的时候通知所有人发生了错误");
        }
        logger.info("有连接关闭！ 当前在线人数" + onlineNumber);
    }

    /**
     * 收到客户端的消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message , Session session)
    {

        try {
            logger.info("来自客户端消息：" + message+"客户端的id是："+session.getId());

            NoticeVo msg= JSON.parseObject(message, NoticeVo.class);
//            /**判断是否之前有过聊条，没有就创建之间的链接*/
//            Link link=linkService.getUserLink(msg.getFrom(), msg.getTo());
//            if(link==null){
//                link=new Link();
//                link.setStudentId(msg.getFrom());
//                link.setDoctorId(msg.getTo());
//                linkService.save(link);
//                Integer id=linkService.selectMax();
//                link.setLinkId(id);
//            }
//            Chat chat=new Chat();
//            chat.setLinkId(link.getLinkId());
//            chat.setFromId(msg.getFrom());
//            chat.setToId(msg.getTo());
//            chat.setSendTime(new Date());
//            chat.setContent(msg.getMessage());
//            chatService.save(chat);
            sendMessageTo(message,String.valueOf(msg.getTo()));
        }
        catch (Exception e){
            logger.info("发生了错误了");
        }

    }


    public static void sendMessageTo(String message, String toId) throws IOException {
        for (WsController item : clients.values()) {
            if (item.id.equals(toId) ) {
                item.session.getAsyncRemote().sendText(message);
                break;
            }
        }
    }


    public void sendMessageAll(String message,String fromId) throws IOException {
        for (WsController item : clients.values()) {
            item.session.getAsyncRemote().sendText(message);
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineNumber;
    }

}